namespace Pay.Core {
	using System;
	using System.Drawing;
	using System.Drawing.Drawing2D;
	using System.Drawing.Imaging;
	using System.Drawing.Text;
	using System.IO;

	public class ImageHelper {
		private static bool _isloadjpegcodec = false;
		private static ImageCodecInfo _jpegcodec = null;

		public static Font CreateFont(string fontFile, float fontSize, FontStyle fontStyle, GraphicsUnit graphicsUnit, byte gdiCharSet) {
			PrivateFontCollection fonts = new PrivateFontCollection();
			fonts.AddFontFile(fontFile);
			return new Font(fonts.Families[0], fontSize, fontStyle, graphicsUnit, gdiCharSet);
		}

		public static void CreateThumbnail(string sourceFilename, string destFilename, int width, int height) {
			Image image = Image.FromFile(sourceFilename);
			if ((image.Width <= width) || (image.Height <= height)) {
				File.Copy(sourceFilename, destFilename, true);
				image.Dispose();
			} else {
				int t_width = image.Width;
				int t_height = image.Height;
				float rate = ((float)height) / ((float)t_height);
				if ((((float)width) / ((float)t_width)) < rate) {
					rate = ((float)width) / ((float)t_width);
				}
				width = (int)(t_width * rate);
				height = (int)(t_height * rate);
				Image image2 = new Bitmap(width, height);
				Graphics graphics = Graphics.FromImage(image2);
				graphics.Clear(Color.White);
				graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
				graphics.SmoothingMode = SmoothingMode.HighQuality;
				graphics.DrawImage(image, new Rectangle(0, 0, width, height), new Rectangle(0, 0, t_width, t_height), GraphicsUnit.Pixel);
				EncoderParameters encoderParams = new EncoderParameters();
				EncoderParameter parameter = new EncoderParameter(Encoder.Quality, 100L);
				encoderParams.Param[0] = parameter;
				ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
				ImageCodecInfo encoder = null;
				for (int i = 0; i < imageEncoders.Length; i++) {
					if (imageEncoders[i].FormatDescription.Equals("JPEG")) {
						encoder = imageEncoders[i];
						break;
					}
				}
				image2.Save(destFilename, encoder, encoderParams);
				encoderParams.Dispose();
				parameter.Dispose();
				image.Dispose();
				image2.Dispose();
				graphics.Dispose();
			}
		}

		public static byte[] CreateThumbnail(string fileName, int width, int height) {
			FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
			try {
				byte[] buffur = new byte[fs.Length];
				fs.Read(buffur, 0, (int)fs.Length);

				return CreateThumbnail(buffur, width, height);
			} catch {
				return null;
			} finally {
				if (fs != null) {
					fs.Close();
				}
			}
		}
		/// <summary>
		/// 创建缩略图，type=1.按长宽切中间图，type=2等比例,中间height=0，就是按width比例缩
		/// </summary>
		/// <returns>The thumbnail.</returns>
		/// <param name="type">1.按长宽切中间图，2等比例</param>
		/// <param name="file_byte">File byte.</param>
		/// <param name="width">Width.</param>
		/// <param name="height">Height.</param>
		public static byte[] CreateThumbnail(byte[] file_byte, int width, int height, int type = 2, int quality = 0) {
			MemoryStream ms = new MemoryStream(file_byte);
			Image image = Image.FromStream(ms);

			if ((image.Width <= width) || (image.Height <= height))
				return file_byte;

			if (type == 1)
				return CreateThumbnailByCut(image, width, height, quality == 1);

			int t_width = image.Width;
			int t_height = image.Height;
			if (height != 0) {
				float rate = ((float)height) / ((float)t_height);
				if ((((float)width) / ((float)t_width)) < rate) {
					rate = ((float)width) / ((float)t_width);
				}
				width = (int)(t_width * rate);
				height = (int)(t_height * rate);
			} else {
				height = image.Width / width * image.Height;
			}
			Image image2 = new Bitmap(width, height);
			Graphics graphics = Graphics.FromImage(image2);
			graphics.Clear(Color.White);
			graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
			graphics.SmoothingMode = SmoothingMode.HighQuality;
			graphics.DrawImage(image, new Rectangle(0, 0, width, height),
							   new Rectangle(0, 0, t_width, t_height), GraphicsUnit.Pixel);

			ms = new MemoryStream();
			if (quality == 1) {
				EncoderParameters encoderParams = new EncoderParameters();
				EncoderParameter parameter = new EncoderParameter(Encoder.Quality, 100L);
				encoderParams.Param[0] = parameter;
				ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
				ImageCodecInfo encoder = null;
				for (int i = 0; i < imageEncoders.Length; i++) {
					if (imageEncoders[i].FormatDescription.Equals("JPEG")) {
						encoder = imageEncoders[i];
						break;
					}
				}
				//ImageFormat format = image2.RawFormat;
				image2.Save(ms, encoder, encoderParams);
			} else
				image2.Save(ms, ImageFormat.Jpeg);

			byte[] buffer = new byte[ms.Length];
			ms.Seek(0, SeekOrigin.Begin);
			ms.Read(buffer, 0, buffer.Length);

			image.Dispose();
			image2.Dispose();
			graphics.Dispose();

			return buffer;
		}

		public static byte[] CreateThumbnailByCut(Image image, int width, int height, bool is_quality) {
			//模版的宽高比例
			double templateRate = (double)width / height;
			//原图片的宽高比例
			double initRate = (double)image.Width / image.Height;
			//原图与模版比例相等，直接缩放
			if (Math.Round(templateRate, 2).ToString() == Math.Round(initRate, 2).ToString()) {
				//按模版大小生成最终图片
				var templateImage = new Bitmap(width, height);
				Graphics templateg = Graphics.FromImage(templateImage);
				templateg.InterpolationMode = InterpolationMode.High;
				templateg.SmoothingMode = SmoothingMode.HighQuality;
				templateg.Clear(Color.White);
				templateg.DrawImage(image, new Rectangle(0, 0, width, height),
									new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel);
				var ms = new MemoryStream();
				templateImage.Save(ms, ImageFormat.Jpeg);
				byte[] buffer = new byte[ms.Length];
				ms.Seek(0, SeekOrigin.Begin);
				ms.Read(buffer, 0, buffer.Length);

				templateg.Dispose();
				templateImage.Dispose();
				image.Dispose();

				return buffer;
			}
			//原图与模版比例不等，裁剪后缩放
			else {
				//裁剪对象
				Image pickedImage = null;
				Graphics pickedg = null;
				//定位
				//原图裁剪定位
				Rectangle fromr = new Rectangle(0, 0, 0, 0);
				//目标定位
				Rectangle tor = new Rectangle(0, 0, 0, 0);
				//宽为标准进行裁剪
				if (templateRate > initRate) {
					//裁剪对象实例化
					pickedImage = new Bitmap(image.Width, (int)Math.Floor(image.Width / templateRate));
					pickedg = Graphics.FromImage(pickedImage);
					//裁剪源定位
					fromr.X = 0;
					fromr.Y = (int)Math.Floor((image.Height - image.Width / templateRate) / 2);
					fromr.Width = image.Width;
					fromr.Height = (int)Math.Floor(image.Width / templateRate);
					//裁剪目标定位
					tor.X = 0;
					tor.Y = 0;
					tor.Width = image.Width;
					tor.Height = (int)Math.Floor(image.Width / templateRate);
				}
				//高为标准进行裁剪
				else {
					pickedImage = new Bitmap((int)Math.Floor(image.Height * templateRate), image.Height);
					pickedg = Graphics.FromImage(pickedImage);
					fromr.X = (int)Math.Floor((image.Width - image.Height * templateRate) / 2);
					fromr.Y = 0;
					fromr.Width = (int)Math.Floor(image.Height * templateRate);
					fromr.Height = image.Height;
					tor.X = 0;
					tor.Y = 0;
					tor.Width = (int)Math.Floor(image.Height * templateRate);
					tor.Height = image.Height;
				}
				//设置质量
				pickedg.InterpolationMode = InterpolationMode.HighQualityBicubic;
				pickedg.SmoothingMode = SmoothingMode.HighQuality;
				//裁剪
				pickedg.DrawImage(image, tor, fromr, GraphicsUnit.Pixel);
				//按模版大小生成最终图片
				Image templateImage = new Bitmap(width, height);
				var templateg = Graphics.FromImage(templateImage);
				templateg.InterpolationMode = InterpolationMode.High;
				templateg.SmoothingMode = SmoothingMode.HighQuality;
				templateg.Clear(Color.White);
				templateg.DrawImage(pickedImage, new Rectangle(0, 0, width, height),
									new Rectangle(0, 0, pickedImage.Width, pickedImage.Height), GraphicsUnit.Pixel);

				var ms = new MemoryStream();
				if (!is_quality)
					templateImage.Save(ms, ImageFormat.Jpeg);
				else {
					//关键质量控制
					//获取系统编码类型数组,包含了jpeg,bmp,png,gif,tiff
					ImageCodecInfo[] icis = ImageCodecInfo.GetImageEncoders();
					ImageCodecInfo ici = null;
					foreach (ImageCodecInfo i in icis) {
						if (i.MimeType == "image/jpeg") {
							//|| i.MimeType == "image/bmp" || i.MimeType == "image/png" || i.MimeType == "image/gif") {
							ici = i;
						}
					}
					EncoderParameters ep = new EncoderParameters(1);
					ep.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
					//保存缩略图
					//templateImage.Save("/Users/ming/Downloads/1.JPG", ImageFormat.Jpeg);
					templateImage.Save(ms, ici, ep);
				}

				byte[] buffer = new byte[ms.Length];
				ms.Seek(0, SeekOrigin.Begin);
				ms.Read(buffer, 0, buffer.Length);

				//释放资源
				templateg.Dispose();
				templateImage.Dispose();
				pickedg.Dispose();
				pickedImage.Dispose();
				//释放资源
				image.Dispose();

				return buffer;
			}
		}

		public static MemoryStream GenerateCheckCode(out string checkCode) {
			int num;
			MemoryStream stream2;
			checkCode = string.Empty;
			//Color color = ColorTranslator.FromHtml("#1AE61A");
			char[] chArray = new char[] {
				'2', '3', '4', '5', '6', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J',
				'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'W', 'X', 'Y'
			 };
			Random random = new Random();
			for (num = 0; num < 4; num++) {
				checkCode = checkCode + chArray[random.Next(chArray.Length)];
			}
			int width = 0x55;
			Bitmap image = new Bitmap(width, 30);
			Graphics graphics = Graphics.FromImage(image);
			Random random2 = new Random(DateTime.Now.Millisecond);
			//Brush brush = new SolidBrush(Color.FromArgb(0x47775b));
			graphics.Clear(ColorTranslator.FromHtml("#EBFDDF"));
			using (StringFormat format = new StringFormat()) {
				format.Alignment = StringAlignment.Center;
				format.LineAlignment = StringAlignment.Center;
				format.FormatFlags = StringFormatFlags.NoWrap;
				Matrix matrix = new Matrix();
				float x = -25f;
				float y = 0f;
				graphics.SmoothingMode = SmoothingMode.AntiAlias;
				for (num = 0; num < checkCode.Length; num++) {
					int num5 = random2.Next(20, 0x18);
					Font font = CreateFont(IOHelper.GetMapPath("fonts", "checkCode.ttf"), (float)num5, FontStyle.Bold, GraphicsUnit.Point, 0);
					char ch = checkCode[num];
					SizeF ef = graphics.MeasureString(ch.ToString(), font);
					matrix.RotateAt((float)random2.Next(-15, 10), new PointF(x + (ef.Width / 2f), y + (ef.Height / 2f)));
					graphics.Transform = matrix;
					graphics.DrawString(checkCode[num].ToString(), font, Brushes.Green, new RectangleF(x, y, (float)image.Width, (float)image.Height), format);
					x += (ef.Width * 3f) / 5f;
					y += 0f;
					graphics.RotateTransform(0f);
					matrix.Reset();
					font.Dispose();
				}
			}
			//Pen pen = new Pen(Color.Black, 0f);
			MemoryStream stream = new MemoryStream();
			try {
				image.Save(stream, ImageFormat.Png);
				stream2 = stream;
			} finally {
				image.Dispose();
				graphics.Dispose();
			}
			return stream2;
		}

		public static void GenerateImageWatermark(string originalPath, string watermarkPath, string targetPath, int position, int opacity, int quality) {
			Image image = null;
			Image image2 = null;
			ImageAttributes imageAttr = null;
			Graphics graphics = null;
			try {
				image = Image.FromFile(originalPath);
				image2 = new Bitmap(watermarkPath);
				if ((image2.Height >= image.Height) || (image2.Width >= image.Width)) {
					image.Save(targetPath);
				} else {
					float num;
					if ((quality < 0) || (quality > 100)) {
						quality = 80;
					}
					if ((opacity > 0) && (opacity <= 10)) {
						num = ((float)opacity) / 10f;
					} else {
						num = 0.5f;
					}
					int x = 0;
					int y = 0;
					switch (position) {
						case 1:
							x = (int)(image.Width * 0.01f);
							y = (int)(image.Height * 0.01f);
							break;

						case 2:
							x = ((int)(image.Width * 0.5f)) - (image2.Width / 2);
							y = (int)(image.Height * 0.01f);
							break;

						case 3:
							x = ((int)(image.Width * 0.99f)) - image2.Width;
							y = (int)(image.Height * 0.01f);
							break;

						case 4:
							x = (int)(image.Width * 0.01f);
							y = ((int)(image.Height * 0.5f)) - (image2.Height / 2);
							break;

						case 5:
							x = ((int)(image.Width * 0.5f)) - (image2.Width / 2);
							y = ((int)(image.Height * 0.5f)) - (image2.Height / 2);
							break;

						case 6:
							x = ((int)(image.Width * 0.99f)) - image2.Width;
							y = ((int)(image.Height * 0.5f)) - (image2.Height / 2);
							break;

						case 7:
							x = (int)(image.Width * 0.01f);
							y = ((int)(image.Height * 0.99f)) - image2.Height;
							break;

						case 8:
							x = ((int)(image.Width * 0.5f)) - (image2.Width / 2);
							y = ((int)(image.Height * 0.99f)) - image2.Height;
							break;

						case 9:
							x = ((int)(image.Width * 0.99f)) - image2.Width;
							y = ((int)(image.Height * 0.99f)) - image2.Height;
							break;
					}
					ColorMap map = new ColorMap {
						OldColor = Color.FromArgb(0xff, 0, 0xff, 0),
						NewColor = Color.FromArgb(0, 0, 0, 0)
					};
					ColorMap[] mapArray = new ColorMap[] { map };
					float[][] numArray2 = new float[5][];
					float[] numArray3 = new float[5];
					numArray3[0] = 1f;
					numArray2[0] = numArray3;
					numArray3 = new float[5];
					numArray3[1] = 1f;
					numArray2[1] = numArray3;
					numArray3 = new float[5];
					numArray3[2] = 1f;
					numArray2[2] = numArray3;
					numArray3 = new float[5];
					numArray3[3] = num;
					numArray2[3] = numArray3;
					numArray3 = new float[5];
					numArray3[4] = 1f;
					numArray2[4] = numArray3;
					float[][] newColorMatrix = numArray2;
					ColorMatrix matrix = new ColorMatrix(newColorMatrix);
					imageAttr = new ImageAttributes();
					imageAttr.SetRemapTable(mapArray, ColorAdjustType.Bitmap);
					imageAttr.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
					graphics = Graphics.FromImage(image);
					graphics.DrawImage(image2, new Rectangle(x, y, image2.Width, image2.Height), 0, 0, image2.Width, image2.Height, GraphicsUnit.Pixel, imageAttr);
					EncoderParameters encoderParams = new EncoderParameters();
					encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, new long[] { (long)quality });
					if (GetJPEGCodec() != null) {
						image.Save(targetPath, _jpegcodec, encoderParams);
					} else {
						image.Save(targetPath);
					}
				}
			} catch (Exception exception) {
				throw exception;
			} finally {
				if (graphics != null) {
					graphics.Dispose();
				}
				if (imageAttr != null) {
					imageAttr.Dispose();
				}
				if (image2 != null) {
					image2.Dispose();
				}
				if (image != null) {
					image.Dispose();
				}
			}
		}

		public static void GenerateTextWatermark(string originalPath, string targetPath, string text, int textSize, string textFont, int position, int quality) {
			Image image = null;
			Graphics graphics = null;
			try {
				image = Image.FromFile(originalPath);
				graphics = Graphics.FromImage(image);
				if ((quality < 0) || (quality > 100)) {
					quality = 80;
				}
				Font font = new Font(textFont, (float)textSize, FontStyle.Regular, GraphicsUnit.Pixel);
				SizeF ef = graphics.MeasureString(text, font);
				float x = 0f;
				float y = 0f;
				switch (position) {
					case 1:
						x = image.Width * 0.01f;
						y = image.Height * 0.01f;
						break;

					case 2:
						x = (image.Width * 0.5f) - (ef.Width / 2f);
						y = image.Height * 0.01f;
						break;

					case 3:
						x = (image.Width * 0.99f) - ef.Width;
						y = image.Height * 0.01f;
						break;

					case 4:
						x = image.Width * 0.01f;
						y = (image.Height * 0.5f) - (ef.Height / 2f);
						break;

					case 5:
						x = (image.Width * 0.5f) - (ef.Width / 2f);
						y = (image.Height * 0.5f) - (ef.Height / 2f);
						break;

					case 6:
						x = (image.Width * 0.99f) - ef.Width;
						y = (image.Height * 0.5f) - (ef.Height / 2f);
						break;

					case 7:
						x = image.Width * 0.01f;
						y = (image.Height * 0.99f) - ef.Height;
						break;

					case 8:
						x = (image.Width * 0.5f) - (ef.Width / 2f);
						y = (image.Height * 0.99f) - ef.Height;
						break;

					case 9:
						x = (image.Width * 0.99f) - ef.Width;
						y = (image.Height * 0.99f) - ef.Height;
						break;
				}
				graphics.DrawString(text, font, new SolidBrush(Color.White), (float)(x + 1f), (float)(y + 1f));
				graphics.DrawString(text, font, new SolidBrush(Color.Black), x, y);
				EncoderParameters encoderParams = new EncoderParameters();
				encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, new long[] { (long)quality });
				if (GetJPEGCodec() != null) {
					image.Save(targetPath, _jpegcodec, encoderParams);
				} else {
					image.Save(targetPath);
				}
			} catch (Exception exception) {
				throw exception;
			} finally {
				if (graphics != null) {
					graphics.Dispose();
				}
				if (image != null) {
					image.Dispose();
				}
			}
		}

		public static ImageCodecInfo GetJPEGCodec() {
			if (!_isloadjpegcodec) {
				ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
				foreach (ImageCodecInfo info in imageEncoders) {
					if (info.MimeType.IndexOf("jpeg") > -1) {
						_jpegcodec = info;
						break;
					}
				}
				_isloadjpegcodec = true;
			}
			return _jpegcodec;
		}

		public static void TranserImageFormat(string originalImagePath, string newFormatImagePath, ImageFormat fortmat) {
			new Bitmap(originalImagePath).Save(newFormatImagePath, ImageFormat.Jpeg);
		}

		public static byte[] StreamToBytes(string filename) {
			Image image = null;
			try {
				image = Image.FromFile(filename);
				ImageFormat format = image.RawFormat;
				using (MemoryStream ms = new MemoryStream()) {
					if (format.Equals(ImageFormat.Jpeg)) {
						image.Save(ms, ImageFormat.Jpeg);
					} else if (format.Equals(ImageFormat.Png)) {
						image.Save(ms, ImageFormat.Png);
					} else if (format.Equals(ImageFormat.Bmp)) {
						image.Save(ms, ImageFormat.Bmp);
					} else if (format.Equals(ImageFormat.Gif)) {
						image.Save(ms, ImageFormat.Gif);
					} else if (format.Equals(ImageFormat.Icon)) {
						image.Save(ms, ImageFormat.Icon);
					}
					byte[] buffer = new byte[ms.Length];
					ms.Seek(0, SeekOrigin.Begin);
					ms.Read(buffer, 0, buffer.Length);
					return buffer;
				}
			} catch {
				return null;
			} finally {
				if (image != null)
					image.Dispose();
			}
		}

		public static byte[] StreamToBytes(Stream stream) {
			Image image = null;
			try {
				image = Image.FromStream(stream);
				ImageFormat format = image.RawFormat;
				using (MemoryStream ms = new MemoryStream()) {
					if (format.Equals(ImageFormat.Jpeg)) {
						image.Save(ms, ImageFormat.Jpeg);
					} else if (format.Equals(ImageFormat.Png)) {
						image.Save(ms, ImageFormat.Png);
					} else if (format.Equals(ImageFormat.Bmp)) {
						image.Save(ms, ImageFormat.Bmp);
					} else if (format.Equals(ImageFormat.Gif)) {
						image.Save(ms, ImageFormat.Gif);
					} else if (format.Equals(ImageFormat.Icon)) {
						image.Save(ms, ImageFormat.Icon);
					}
					byte[] buffer = new byte[ms.Length];
					ms.Seek(0, SeekOrigin.Begin);
					ms.Read(buffer, 0, buffer.Length);
					return buffer;
				}
			} catch {
				return null;
			} finally {
				if (image != null)
					image.Dispose();
			}
		}
	}
}
